package com.dmzc.stage2.chapter15;

/***
 * 给Thread加上一层封装，在run的逻辑里执行任务单元前后加上通知的逻辑
 * @param <T>
 */
public class ObservableThread<T> extends Thread
        implements Observable {
    private final TaskLifecycle<T> lifecycle;
    private final Task<T> task;
    private Cycle cycle;

    public ObservableThread(TaskLifecycle<T> lifecycle, Task<T> task) {
        super();
        if (task == null)
            throw new IllegalArgumentException("The task is required.");
        this.lifecycle = lifecycle;
        this.task = task;
    }

    public ObservableThread(Task<T> task){
        this(new TaskLifecycle.EmptyLifecycle<>(),task);
    }

    /**
     * 获取当前任务的生命周期状态
     *
     * @return
     */
    @Override
    public Cycle getCycle() {
        return this.cycle;
    }

    @Override
    public final void run() {
        this.update(Cycle.STARTED,null,null);
        try{
            this.update(Cycle.RUNNING,null,null);
            T result=this.task.call();
            this.update(Cycle.DONE,result,null);
        }catch (Exception e){
            this.update(Cycle.ERROR,null,e);
        }
    }
    private void update(Cycle cycle,T result,Exception e){
        this.cycle=cycle;
        if (null==lifecycle)
            return;
        try{
            switch (cycle){
                case STARTED:
                    this.lifecycle.onStart(currentThread());
                    break;
                case RUNNING:
                    this.lifecycle.onRunning(currentThread());
                    break;
                case DONE:
                    this.lifecycle.onFinish(currentThread(),result);
                    break;
                case ERROR:
                    this.lifecycle.onError(currentThread(),e);
                    break;
            }
        }catch(Exception ex){
            if (cycle==Cycle.ERROR){
                throw ex;
            }
        }
    }
}
